﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CFM.API;
using CFM.DTO;
using CFM.Common;

namespace CFM
{
    public partial class frmMain : Form
    {
        private TableAPI _tableAPI = null;        
        private TableGroupAPI _tableGroupAPI = null;

        private List<TableGroup> _tableGroupWoking = null;
        private List<Table> _tableWoking = null;
        private List<BillDetail> _billDetailWroking = null;
        private List<Tuple<Bill, List<BillDetail>>> _billWorking = null;
        private Tuple<Bill, List<BillDetail>> _billSelected = null;
        public frmMain()
        {
            InitializeComponent();
            _tableAPI = new TableAPI();
            _tableGroupAPI = new TableGroupAPI();
            _billDetailWroking = new List<BillDetail>();
            _billWorking = new List<Tuple<Bill, List<BillDetail>>>();
            
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            grvProduct.AutoGenerateColumns = false;
            grvOrder.AutoGenerateColumns = false;
            
            LoadTableGroup();
            LoadCbxProductGroup();

            var tableLsit = _tableAPI.GetAll();
            foreach (var item in tableLsit)
            {
                Bill b = new Bill();
                b.TableId = item.TableId;
                b.TableName = item.TableName;
                b.TableGroupName = item.TableGroupName;
                b.Status = false;
                List<BillDetail> detailList = new List<BillDetail>();
                Tuple<Bill, List<BillDetail>> t = new Tuple<Bill, List<BillDetail>>(b, detailList);
                _billWorking.Add(t);
            }

           
            
        }
        private void LoadTableGroup()
        {
            _tableGroupWoking = _tableGroupAPI.GetAll();
            lisTableGroup.DataSource = _tableGroupWoking;            
        }

        private void LoadTable()
        {
            lisTable.Clear();
            if (_tableWoking != null)
            {
                foreach (var item in _tableWoking)
                {
                    ListViewItem lisItem = new ListViewItem();
                    lisItem.Text = item.TableName;
                    lisItem.Name = item.TableId;

                    if (lblTableId.Text != Const.EMPTY_FROMAT && lisItem.Name == lblTableId.Text)
                    {
                        lisItem.BackColor = Color.OrangeRed;                        
                    }                   
                    if (_billWorking.Count == 0)
                        lisItem.ImageIndex = 0;
                    else
                        lisItem.ImageIndex = (_billWorking.Where(r => r.Item1.TableId == item.TableId).FirstOrDefault().Item1.Status ? 1 : 0);
                    lisTable.Items.Add(lisItem);
                }
            }
        }

        private void LoadCbxProductGroup()
        {
            cbxProductGroup.DataSource = (new CategoriesAPI()).GetAllForSale();            

        }        

       
        private void lisTableGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            string value = lisTableGroup.SelectedValue.ToString();
            _tableWoking = _tableAPI.GetTableFromGroupId(value);
            LoadTable();
        }

        private void cbxProductGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            string groupProductId = cbxProductGroup.SelectedValue.ToString();
            grvProduct.DataSource = (new ProductAPI()).GetProductByGroupId(groupProductId);
        }

        private void grvProduct_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0)
                return;
            if (_billSelected == null)
            {
                MessageBox.Show("Hãy chọn bàn trước");
                return;
            }
            foreach (DataGridViewRow row in grvProduct.SelectedRows)
            {
                Product product = row.DataBoundItem as Product;
                BillDetail billDetail = new BillDetail();
                var billDetails = _billSelected.Item2.Where(r => r.ProductId == product.ProductId).ToList();
                if (billDetails.Count == 1)
                {
                    billDetail = billDetails.FirstOrDefault();
                    billDetail.Quantity++;
                    billDetail.DetailTotal = billDetail.Quantity * billDetail.Price;                    
                }
                else
                {
                    billDetail.ProductId = product.ProductId;
                    billDetail.ProductName = product.ProductName;
                    billDetail.Price = product.SalePrice;
                    billDetail.UnitId = product.Unit1Id;
                    billDetail.Quantity = 1;
                    billDetail.DetailTotal = billDetail.Quantity * billDetail.Price;
                    _billSelected.Item2.Add(billDetail);
                    billDetail = null;
                    billDetails = null;
                }
            }
            _billSelected.Item1.Total = _billSelected.Item2.Sum(r => r.DetailTotal);
            _billSelected.Item1.Status = true;
            if(_billSelected.Item1.BillDate == (new DateTime()))
                _billSelected.Item1.BillDate = DateTime.Now;
            lblTotal.Text = string.Format(Const.NUMBER_FORMAT, _billSelected.Item1.Total);
            lblDateEnter.Text = _billSelected.Item1.BillDate.ToString(Const.DATE_TIME_FORMAT);
            RefestGridOrder();
            LoadTable();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (grvOrder.SelectedRows.Count > 0)
            {
                int rowSelected = grvOrder.SelectedRows[0].Index;
                BillDetail selected = grvOrder.SelectedRows[0].DataBoundItem as BillDetail;
                BillDetail billDetail = _billSelected.Item2.Where(r => r.ProductId == selected.ProductId).FirstOrDefault();
                billDetail.Quantity++;
                billDetail.DetailTotal = billDetail.Quantity * billDetail.Price;
                _billSelected.Item1.Total = _billSelected.Item2.Sum(r => r.DetailTotal);
                lblTotal.Text = string.Format(Const.NUMBER_FORMAT, _billSelected.Item1.Total);
                RefestGridOrder();
                grvOrder.Rows[rowSelected].Selected = true;
            }
        }       

        private void btnSubtraction_Click(object sender, EventArgs e)
        {
            if (grvOrder.SelectedRows.Count > 0)
            {
                int rowSelected = grvOrder.SelectedRows[0].Index;
                BillDetail selected = grvOrder.SelectedRows[0].DataBoundItem as BillDetail;
                BillDetail billDetail = _billSelected.Item2.Where(r => r.ProductId == selected.ProductId).FirstOrDefault();                
                billDetail.Quantity--;
                if (billDetail.Quantity <= 0)
                    billDetail.Quantity = 1;
                billDetail.DetailTotal = billDetail.Quantity * billDetail.Price;
                _billSelected.Item1.Total = _billSelected.Item2.Sum(r => r.DetailTotal);
                lblTotal.Text = string.Format(Const.NUMBER_FORMAT, _billSelected.Item1.Total);
                RefestGridOrder();
                grvOrder.Rows[rowSelected].Selected = true;
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (grvOrder.SelectedRows.Count > 0)
            {
                BillDetail selected = grvOrder.SelectedRows[0].DataBoundItem as BillDetail;
                BillDetail billDetail = _billSelected.Item2.Where(r => r.ProductId == selected.ProductId).FirstOrDefault();
                _billSelected.Item2.Remove(billDetail);
                _billSelected.Item1.Total = _billSelected.Item2.Sum(r => r.DetailTotal);
                lblTotal.Text = string.Format(Const.NUMBER_FORMAT, _billSelected.Item1.Total);
                if (_billSelected.Item2.Count == 0)
                {
                    _billSelected.Item1.Status = false;
                }
                RefestGridOrder();
                LoadTable();
            }
        }
        private void RefestGridOrder()
        {
            grvOrder.DataSource = null;
            grvOrder.DataSource = _billSelected.Item2.ToList();
        }

        private void lisTable_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lisTable.SelectedItems.Count > 0)
            {
                string tableId = lisTable.SelectedItems[0].Name;
                _billSelected = _billWorking.Where(r => r.Item1.TableId == tableId).FirstOrDefault();
                RefestGridOrder();

                lblTableName.Text = _billSelected.Item1.TableName + ", " + _billSelected.Item1.TableGroupName;
                lblTableId.Text = _billSelected.Item1.TableId.Trim();
                if (_billSelected.Item1.Status)
                    lblDateEnter.Text = _billSelected.Item1.BillDate.ToString(Const.DATE_TIME_FORMAT);
                else
                    lblDateEnter.Text = Const.EMPTY_FROMAT;
                lblTotal.Text = string.Format(Const.NUMBER_FORMAT, _billSelected.Item1.Total);                
            }
        }

        private void SaveBill()
        {
            if (_billSelected != null && _billSelected.Item2.Count > 0)
            {
                BillAPI billApi = new BillAPI();

                if (billApi.Create(_billSelected))
                {
                    MessageBox.Show("Lưu thành công!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);                   
                    _billSelected.Item1.Status = false;
                    _billSelected.Item1.Total = 0;
                    _billSelected.Item1.BillDate = new DateTime();
                    _billSelected.Item2.RemoveRange(0, _billSelected.Item2.Count);
                    
                    lblDateEnter.Text = Const.EMPTY_FROMAT;
                    lblTableName.Text = Const.EMPTY_FROMAT;
                    lblTableId.Text = Const.EMPTY_FROMAT;                    
                    lblTotal.Text = Const.EMPTY_FROMAT;
                    LoadTable();
                    RefestGridOrder();
                }
                else
                    MessageBox.Show("Lưu thách bại! \n Lỗi: "+ billApi.error, "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
        }
        private void Print()
        {
            if (_billSelected != null && _billSelected.Item2.Count > 0)
            {
                frmPrintBill frm = new frmPrintBill();
                frm.StartPosition = FormStartPosition.CenterParent;
                frm.LoadReport(_billSelected.Item1, _billSelected.Item2);
                frm.ShowDialog();
            }
        }
        private void btnSave_Click(object sender, EventArgs e)
        {
            SaveBill();
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            Print();   
        }

        private void btnPrintSave_Click(object sender, EventArgs e)
        {
            Print();
            SaveBill();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("Bạn có chắc là muốn thoát không?", "Cảnh báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                e.Cancel = false;
            }
            else
                e.Cancel = true;
        }        

        private void grvProduct_MouseLeave(object sender, EventArgs e)
        {
            pnlAdd.Visible = false;
        }

        private void grvProduct_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Y <= 22)
                return;
            pnlAdd.Visible = true;
            pnlAdd.Left = grvProduct.Left + grvProduct.Width;
            pnlAdd.Top = groupBox1.Top + e.Y + 51; 
        }
    }
}
